package com.aiti.lulian.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.utils.message.Message;
import com.aiti.lulian.dto.CardBaseInfoRankDto;
import com.aiti.lulian.dto.CardUserAuthenticationDto;
import com.aiti.lulian.dto.CardUserIncreaseRankDto;
import com.aiti.lulian.dto.CardUserRankUserVisitHistoryDto;
import com.aiti.lulian.entity.*;
import com.aiti.lulian.entity.newCard.CardBaseInfo;
import com.aiti.lulian.factory.RankIncreaseTaskFactory;
import com.aiti.lulian.mapper.CardRankTaskUserCompleteMapper;
import com.aiti.lulian.mapper.CardUserAuthenticationMapper;
import com.aiti.lulian.mapper.newCard.CardPersonalBaseInfoMapper;
import com.aiti.lulian.service.*;
import com.aiti.lulian.strategy.task.RankIncreaseTaskStrategy;
import com.aiti.lulian.utils.SmsCompont;
import com.aiti.lulian.vo.CardBaseInfoRankListVo;
import com.aiti.lulian.vo.CardRankTaskUserVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;


import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 名片排名任务选项表 服务实现类
 * </p>
 *
 * @author 
 * @since 2025-08-14
 */
@Service
public class CardRankService {

    private static final String USER_AUTHENTICATION_KEY = "user_authentication_sms:%s";

    @Value("${aliyun.sms.auth-template}")
    private String smsTemplateId;
    /** 短信验证码过期时间 */
    private static final long CODE_EXPIRED = 1000 * 60 * 1;


    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private SmsCompont smsCompont;

    @Autowired
    private CardPersonalBaseInfoMapper cardBaseInfoMapper;
    @Autowired
    private CardUserRankUserChangeHistoryService cardUserRankUserChangeHistoryService;

    @Autowired
    private CardUserAuthenticationService cardUserAuthenticationService;

    @Autowired
    private CardUserAuthenticationMapper cardUserAuthenticationMapper;
    @Autowired
    private CardRankTaskUserCompleteMapper cardRankTaskUserCompleteMapper;
    @Autowired
    private CardUserRankTaskHistoryService cardUserRankTaskHistoryService;
    @Autowired
    private CardUserRankUserVisitHistoryService cardUserRankUserVisitHistoryService;

    @Autowired
    private RankIncreaseTaskFactory taskFactory;


    /**
     * 名片人气榜页面列表
     * @param dto
     * @return
     */
    public List<CardBaseInfoRankListVo> userCardRankList(CardBaseInfoRankDto dto){
        int pageNum = dto.getPageNum() != null ? dto.getPageNum() : 0;
        int pageSize = dto.getPageSize() != null ? dto.getPageSize() : 20;
        Page page = new Page();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        List<CardBaseInfoRankListVo> cardBaseInfoRankListVos = cardBaseInfoMapper.userCardRankList(page, dto);
        return cardBaseInfoRankListVos;


    }

    /**
     * 名片人气榜页面点击切换图标
     * @param userId
     * @return
     */
    public Message changeUserCard(String userId){
        Date date = new Date();
        DateTime beginMonthDate = DateUtil.beginOfMonth(date);
        DateTime endMonthDate = DateUtil.endOfMonth(date);
        LambdaQueryWrapper<CardUserRankUserChangeHistory> wrapper = new LambdaQueryWrapper<CardUserRankUserChangeHistory>().eq(CardUserRankUserChangeHistory::getUserId, userId)
                .ge(CardUserRankUserChangeHistory::getBaseCreateTime, beginMonthDate)
                .le(CardUserRankUserChangeHistory::getBaseCreateTime, endMonthDate);

        int count = cardUserRankUserChangeHistoryService.count(wrapper);
        if(count > 3){
            return Message.fail("请勿频繁刷榜，每月限上榜3次");
        }else{
            CardUserRankUserChangeHistory cardUserRankUserChangeHistory = new CardUserRankUserChangeHistory();
            cardUserRankUserChangeHistory.setUserId(userId).setBaseId(IdUtil.simpleUUID());
            cardUserRankUserChangeHistoryService.save(cardUserRankUserChangeHistory);
            return Message.success();
        }

    }

    /**
     * 当前用户排名情况
     * @param dto
     * @return
     */
    public Message currentUserRank(CardBaseInfoRankDto dto){
        String baseId = dto.getBaseId();
        if(StringUtils.isEmpty(baseId)){
            return Message.fail("名片id不能为空");
        }
        List<CardBaseInfoRankListVo> userCardRankByCondition = cardBaseInfoMapper.getUserCardRankByCondition(dto);
        Map map = new HashMap();
        if(!CollectionUtils.isEmpty(userCardRankByCondition)){
            CardBaseInfoRankListVo cardBaseInfoRankListVo = userCardRankByCondition.get(0);
            int rankNum = cardBaseInfoRankListVo.getRankNum();
            long cardRankBrowseCount = cardBaseInfoRankListVo.getCardRankBrowseCount();
            long cardRankTotalScore = cardBaseInfoRankListVo.getCardRankTotalScore();
            map.put("currentUserRank", String.valueOf(rankNum));
            map.put("currentUserBrowsed", String.valueOf(cardRankBrowseCount));
            map.put("currentUserRankTotalScore", String.valueOf(cardRankTotalScore));

            if(rankNum != 1){
                CardBaseInfoRankDto newDto = new CardBaseInfoRankDto();
                newDto.setRankNum(rankNum - 1);
                userCardRankByCondition = cardBaseInfoMapper.getUserCardRankByCondition(newDto);
                if(!CollectionUtils.isEmpty(userCardRankByCondition)){
                    CardBaseInfoRankListVo lastRankVo = userCardRankByCondition.get(0);
                    long lastCardRankTotalScore = lastRankVo.getCardRankTotalScore();
                    map.put("diffWithPreviousRank", String.valueOf(lastCardRankTotalScore - cardRankTotalScore));
                }
            }else{
                map.put("diffWithPreviousRank", String.valueOf(0));
            }



        }else{
            map.put("currentUserRank", "9999+");
            map.put("currentUserBrowsed", String.valueOf(0));

        }
        return Message.success(map);

    }

    /**
     * 发送短信验证码
     * @param mobile
     * @return
     */
    public Message sendCode(String mobile){

        String key = String.format(USER_AUTHENTICATION_KEY, mobile);
        String captcha = stringRedisTemplate.opsForValue().get(key);
        if(!StringUtils.isEmpty(captcha)){
            return Message.fail("重复发送短信验证码过于频繁,请稍后再试");
        }

        int code = RandomUtil.randomInt(100000, 999999);

        boolean isSuccess = smsCompont.send(mobile, smsTemplateId, String.valueOf(code));
        stringRedisTemplate.opsForValue().set(key, String.valueOf(code), CODE_EXPIRED, TimeUnit.MILLISECONDS);
        if(!isSuccess){
            return Message.fail("短信发送失败，请联系管理员");
        }else{

            return Message.success("已发送");
        }

    }

    /**
     * 提交认证信息
     * @param dto
     * @return
     */
    public Message submitAuthentication(CardUserAuthenticationDto dto) {
        String mobile = dto.getMobile();
        String userName = dto.getUserName();
        String code = dto.getCode();
        String cardId = dto.getCardId();

        //构建RedisKey
        String key = String.format(USER_AUTHENTICATION_KEY, mobile);
        String recordCode = stringRedisTemplate.opsForValue().get(key);
        //取出Redis中的验证码
        if(StrUtil.isEmpty(recordCode)){

            return Message.fail("验证码已过期！");
        }

        if(!code.equals(recordCode)){
            return Message.fail("验证码错误！");
        }

        String userByCondition = cardUserAuthenticationMapper.getUserByCondition(dto);
        if(StringUtils.isEmpty(userByCondition)){
            return Message.fail("认证失败，请检查名片姓名和认证所填信息是否一致");
        }
        CardBaseInfo cardBaseInfo = cardBaseInfoMapper.queryCardInfoWithExpireTime(cardId);
        if(cardBaseInfo == null){
            return Message.fail("名片不存在");
        }
        Date expireTime = cardBaseInfo.getExpireTime();
        String cardVersion = cardBaseInfo.getCardVersion();

        if(expireTime != null && !"1".equals(cardVersion) && expireTime.getTime() < System.currentTimeMillis()){
            return Message.fail("名片已过期");
        }


        CardUserAuthentication cardUserAuthentication = new CardUserAuthentication();
        cardUserAuthentication.setCardId(cardId).setUserId(cardBaseInfo.getUserId()).setPhone(mobile).setRealname(userName);
        cardUserAuthenticationService.save(cardUserAuthentication);
        return Message.success();


    }

    /**
     * 是否已认证信息
     * @param dto
     * @return
     */
    public Message isAuthenticated(CardUserAuthenticationDto dto){
        String userId = dto.getUserId();
        if(StringUtils.isEmpty(userId)){
            return Message.fail("传参错误，请检查传参");
        }

        String authenticated = cardUserAuthenticationMapper.isAuthenticated(dto);
        if(StringUtils.isEmpty(authenticated)){
            return Message.success(false);
        }else{
            return Message.success(true);
        }

    }

    /**
     * 提升排名页面-任务情况
     * @param
     * @return
     */
    public Message userTaskInfo(CardUserIncreaseRankDto dto){
        String cardId = dto.getCardId();
        if(StringUtils.isEmpty(cardId)){
            return Message.fail("名片id不能为空");
        }
        CardBaseInfo cardBaseInfo = cardBaseInfoMapper.selectById(cardId);
        if(cardBaseInfo == null){
            return Message.fail("名片不存在");
        }

        Date date = new Date();
        DateTime beginOfDay = DateUtil.beginOfDay(date);
        DateTime endOfDay = DateUtil.endOfDay(date);
        String enterpriseId = cardBaseInfo.getEnterpriseId();
        String version = "0";
        if(!StringUtils.isEmpty(enterpriseId)){
            version = "1";
        }
        List<CardRankTaskUserVo> taskList = cardRankTaskUserCompleteMapper.currentUserTaskCompleteList(cardId, version);
        LambdaQueryWrapper<CardUserRankTaskHistory> wrapper = new LambdaQueryWrapper<CardUserRankTaskHistory>().eq(CardUserRankTaskHistory::getCardId, cardId).eq(CardUserRankTaskHistory::getType, "check_in")
                .ge(CardUserRankTaskHistory::getBaseCreateTime, beginOfDay).le(CardUserRankTaskHistory::getBaseCreateTime, endOfDay);
        List<CardUserRankTaskHistory> checkInList = cardUserRankTaskHistoryService.list(wrapper);
        Map map = new HashMap();
        if(!CollectionUtils.isEmpty(checkInList)){
            map.put("checkInFlag", true);
        }else{
            map.put("checkInFlag", false);
        }
        map.put("totalCheckInCount", cardBaseInfo.getCardRankCheckInCount());
        if(!CollectionUtils.isEmpty(taskList)){

            for (CardRankTaskUserVo vo: taskList){
                RankIncreaseTaskStrategy task = taskFactory.getStrategy(vo.getType());
                task.handleTask(vo, dto);
            }

        }
        map.put("cardTask", taskList);
        return Message.success(map);

    }

    public Message finishRead(String cardId) {
        CardBaseInfo info = new CardBaseInfo();
        info.setReadManualFlag("1");
        info.setBaseId(cardId);
        cardBaseInfoMapper.updateById(info);
        return Message.success();
    }

    /**
     * 签到
     * @param cardId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Message checkIn(String cardId){
        CardBaseInfo cardBaseInfo = cardBaseInfoMapper.selectById(cardId);
        if(cardBaseInfo == null){
            return Message.fail("名片不存在");
        }
        Date date = new Date();
        DateTime beginOfDay = DateUtil.beginOfDay(date);
        DateTime endOfDay = DateUtil.endOfDay(date);
        LambdaQueryWrapper<CardUserRankTaskHistory> wrapper = new LambdaQueryWrapper<CardUserRankTaskHistory>().eq(CardUserRankTaskHistory::getCardId, cardId).eq(CardUserRankTaskHistory::getType, "check_in")
                .ge(CardUserRankTaskHistory::getBaseCreateTime, beginOfDay).le(CardUserRankTaskHistory::getBaseCreateTime, endOfDay);
        List<CardUserRankTaskHistory> checkInList = cardUserRankTaskHistoryService.list(wrapper);
        if(!CollectionUtils.isEmpty(checkInList)){
            return Message.fail("今日已签到过，请勿重复签到");
        }

        CardUserRankTaskHistory cardUserRankTaskHistory = new CardUserRankTaskHistory();
        cardUserRankTaskHistory.setCardId(cardId);
        cardUserRankTaskHistory.setUserId(cardBaseInfo.getUserId());
        cardUserRankTaskHistory.setType("check_in");
        cardUserRankTaskHistory.setScore(50L);
        cardUserRankTaskHistoryService.save(cardUserRankTaskHistory);

        CardBaseInfo updateCardBaseInfo = new CardBaseInfo();
        updateCardBaseInfo.setBaseId(cardId);
        updateCardBaseInfo.setCardRankCheckInCount(cardBaseInfo.getCardRankCheckInCount()+1);
        updateCardBaseInfo.setCardRankTotalScore(cardBaseInfo.getCardRankTotalScore() + 50);
        cardBaseInfoMapper.updateById(updateCardBaseInfo);

        return Message.success();
    }

    /**
     * 名片人气榜记录点击浏览名片
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Message recordBrowse(@Validated CardUserRankUserVisitHistoryDto dto){

        String visitedCardId = dto.getVisitedCardId();

        CardUserRankUserVisitHistory cardUserRankUserVisitHistory = new CardUserRankUserVisitHistory();
        BeanUtils.copyProperties(dto, cardUserRankUserVisitHistory);
        cardUserRankUserVisitHistoryService.save(cardUserRankUserVisitHistory);
        CardBaseInfo cardBaseInfo = cardBaseInfoMapper.selectById(visitedCardId);
        if(cardBaseInfo == null){
            return Message.fail("名片不存在");
        }

        CardBaseInfo updateCardBaseInfo = new CardBaseInfo();
        updateCardBaseInfo.setBaseId(visitedCardId);
        updateCardBaseInfo.setCardRankBrowseCount(cardBaseInfo.getCardRankBrowseCount()+1);
        cardBaseInfoMapper.updateById(updateCardBaseInfo);

        return Message.success();
    }

    /**
     * 完成任务
     * @param dto
     * @return
     */
    public Message completeTask(CardUserIncreaseRankDto dto){
        String type = dto.getType();
        RankIncreaseTaskStrategy task = taskFactory.getStrategy(type);
        if (task == null) {
            return Message.fail("不支持的任务类型");
        }
        String cardId = dto.getCardId();
        CardBaseInfo cardBaseInfo = cardBaseInfoMapper.selectById(cardId);
        if(cardBaseInfo == null){
            return Message.fail("名片不存在");
        }
        return task.handle(dto);

    }


    public void clearScore(){
        cardBaseInfoMapper.clearScore();
    }






}
